{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Auto_gradient_of_tensors.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.6"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/PacktPublishing/Modern-Computer-Vision-with-PyTorch/blob/master/Chapter02/Auto_gradient_of_tensors.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:08:10.067717Z",
          "start_time": "2020-09-25T19:08:09.790849Z"
        },
        "id": "2F97TkDgceZl",
        "outputId": "bcf323f6-b397-4096-f42d-a09525ab514b",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        }
      },
      "source": [
        "import numpy as np\n",
        "import torch\n",
        "x = torch.tensor([[2., -1.], [1., 1.]], requires_grad=True)\n",
        "print(x)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "tensor([[ 2., -1.],\n",
            "        [ 1.,  1.]], requires_grad=True)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:08:10.073796Z",
          "start_time": "2020-09-25T19:08:10.068777Z"
        },
        "id": "oRar4LIhcft7"
      },
      "source": [
        "out = x.pow(2).sum()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:08:10.453263Z",
          "start_time": "2020-09-25T19:08:10.409991Z"
        },
        "id": "hZsXXwYOchAQ"
      },
      "source": [
        "out.backward()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:08:10.719800Z",
          "start_time": "2020-09-25T19:08:10.708500Z"
        },
        "id": "3awLkXAIciTB",
        "outputId": "7f7defa4-4cef-40f0-ddac-4e0861d32b5e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 51
        }
      },
      "source": [
        "x.grad"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "tensor([[ 4., -2.],\n",
              "        [ 2.,  2.]])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 5
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "36KGeXUt0hT_"
      },
      "source": [
        "### Computing gradients for the same case that was present in `Chain_rule.ipynb` notebook in previous chapter"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:09:58.963790Z",
          "start_time": "2020-09-25T19:09:58.960947Z"
        },
        "id": "9MYfARsd0hT_"
      },
      "source": [
        "x = np.array([[1,1]])\n",
        "y = np.array([[0]])\n",
        "x, y = [torch.tensor(i).float() for i in [x,y]]"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:11:27.928978Z",
          "start_time": "2020-09-25T19:11:27.925311Z"
        },
        "id": "qTPQsSk2cjaG"
      },
      "source": [
        "W = [\n",
        "    np.array([[-0.0053, 0.3793],\n",
        "              [-0.5820, -0.5204],\n",
        "              [-0.2723, 0.1896]], dtype=np.float32).T, \n",
        "    np.array([-0.0140, 0.5607, -0.0628], dtype=np.float32), \n",
        "    np.array([[ 0.1528, -0.1745, -0.1135]], dtype=np.float32).T, \n",
        "    np.array([-0.5516], dtype=np.float32)\n",
        "]\n",
        "\n",
        "W = [torch.tensor(i, requires_grad=True) for i in W]"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:11:36.364882Z",
          "start_time": "2020-09-25T19:11:36.361713Z"
        },
        "id": "DquL9NRf0hUE"
      },
      "source": [
        "def feed_forward(inputs, outputs, weights):\n",
        "    pre_hidden = torch.matmul(inputs,weights[0])+ weights[1]\n",
        "    hidden = 1/(1+torch.exp(-pre_hidden))\n",
        "    out = torch.matmul(hidden, weights[2]) + weights[3]\n",
        "    mean_squared_error = torch.mean(torch.square(out - outputs))\n",
        "    return mean_squared_error"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:11:36.653945Z",
          "start_time": "2020-09-25T19:11:36.640255Z"
        },
        "id": "bcyJ2zPd0hUH",
        "outputId": "9989d5be-4aa2-46ce-e748-ff71755ebca1"
      },
      "source": [
        "loss = feed_forward(x, y, W)\n",
        "loss"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "tensor(0.3346, grad_fn=<MeanBackward0>)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 31
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:11:37.478074Z",
          "start_time": "2020-09-25T19:11:37.475342Z"
        },
        "id": "8yPnRjgz0hUJ"
      },
      "source": [
        "loss.backward()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:11:48.459841Z",
          "start_time": "2020-09-25T19:11:48.455483Z"
        },
        "id": "aRvZOyAR0hUL",
        "outputId": "79c407d6-5c74-4272-b06d-325ff32eca73"
      },
      "source": [
        "print([w.grad for w in W])"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "[tensor([[-0.0428,  0.0469,  0.0327],\n",
            "        [-0.0428,  0.0469,  0.0327]]), tensor([-0.0428,  0.0469,  0.0327]), tensor([[-0.6814],\n",
            "        [-0.4255],\n",
            "        [-0.5364]]), tensor([-1.1568])]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "ExecuteTime": {
          "end_time": "2020-09-25T19:12:18.423376Z",
          "start_time": "2020-09-25T19:12:18.418873Z"
        },
        "id": "ppTkD6JQ0hUN",
        "outputId": "48f5f3a6-e613-4d37-c5f9-48fdc0f8d293"
      },
      "source": [
        "updated_W = [w-w.grad for w in W]\n",
        "updated_W"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[tensor([[ 0.0375, -0.6289, -0.3050],\n",
              "         [ 0.4221, -0.5673,  0.1569]], grad_fn=<SubBackward0>),\n",
              " tensor([ 0.0288,  0.5138, -0.0955], grad_fn=<SubBackward0>),\n",
              " tensor([[0.8342],\n",
              "         [0.2510],\n",
              "         [0.4229]], grad_fn=<SubBackward0>),\n",
              " tensor([0.6052], grad_fn=<SubBackward0>)]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 34
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "63LC7Fj_0hUP"
      },
      "source": [
        ""
      ],
      "execution_count": null,
      "outputs": []
    }
  ]
}